#include <sys/epoll.h>
#include <functional>
#include <unordered_map>
#include <memory>
#include <system_error>
#include <vector>
#include <unistd.h>
#include <iostream>

class Reactor {
public:
    using EventHandler = std::function<void(int)>;

    Reactor() : epoll_fd_(epoll_create1(EPOLL_CLOEXEC)) {
        if (epoll_fd_ == -1) {
            throw std::system_error(errno, std::generic_category(), "epoll_create1 failed");
        }
    }

    ~Reactor() {
        if (epoll_fd_ != -1) close(epoll_fd_);
    }

    // 注册事件处理器
    void register_handler(int fd, uint32_t events, EventHandler handler) {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;

        if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
            if (errno == EEXIST) {
                modify_handler(fd, events, handler);
                return;
            }
            throw std::system_error(errno, std::generic_category(), "epoll_ctl ADD failed");
        }

        handlers_[fd] = std::move(handler);
    }

    // 修改事件处理器
    void modify_handler(int fd, uint32_t events, EventHandler handler) {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;

        if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &ev) == -1) {
            throw std::system_error(errno, std::generic_category(), "epoll_ctl MOD failed");
        }

        handlers_[fd] = std::move(handler);
    }

    // 移除事件处理器
    void remove_handler(int fd) {
        if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, nullptr) == -1) {
            throw std::system_error(errno, std::generic_category(), "epoll_ctl DEL failed");
        }
        handlers_.erase(fd);
    }

    // 主事件循环
    void run_loop(int timeout_ms = -1) {
        std::vector<epoll_event> events(MAX_EVENTS);

        while (!should_stop_) {
            int ready = epoll_wait(epoll_fd_, events.data(), MAX_EVENTS, timeout_ms);

            if (ready == -1) {
                if (errno == EINTR) continue; // 被信号中断
                throw std::system_error(errno, std::generic_category(), "epoll_wait failed");
            }

            for (int i = 0; i < ready; ++i) {
                auto it = handlers_.find(events[i].data.fd);
                if (it != handlers_.end()) {
                    it->second(events[i].data.fd); // 调用注册的回调
                }
            }
        }
    }

    void stop() { should_stop_ = true; }

private:
    static constexpr int MAX_EVENTS = 1024;
    int epoll_fd_;
    std::unordered_map<int, EventHandler> handlers_;
    bool should_stop_ = false;
};

/****************** 应用示例 ******************/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <string.h>

class EchoServer {
public:
    EchoServer(Reactor& reactor, uint16_t port) : reactor_(reactor) {
        listen_fd_ = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
        if (listen_fd_ == -1) {
            throw std::system_error(errno, std::generic_category(), "socket failed");
        }

        sockaddr_in addr{};
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = INADDR_ANY;
        addr.sin_port = htons(port);

        if (bind(listen_fd_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
            throw std::system_error(errno, std::generic_category(), "bind failed");
        }

        if (listen(listen_fd_, SOMAXCONN) == -1) {
            throw std::system_error(errno, std::generic_category(), "listen failed");
        }

        // 注册监听套接字事件处理器
        reactor_.register_handler(listen_fd_, EPOLLIN, 
            [this](int fd) { handle_accept(); });
    }

private:
    void handle_accept() {
        sockaddr_in client_addr{};
        socklen_t len = sizeof(client_addr);
        
        int client_fd = accept4(listen_fd_, 
            reinterpret_cast<sockaddr*>(&client_addr), 
            &len, SOCK_NONBLOCK);

        if (client_fd == -1) {
            std::cerr << "accept failed: " << strerror(errno) << std::endl;
            return;
        }

        std::cout << "New connection from: " 
                  << inet_ntoa(client_addr.sin_addr) << ":"
                  << ntohs(client_addr.sin_port) << std::endl;

        // 注册客户端事件处理器
        reactor_.register_handler(client_fd, EPOLLIN | EPOLLRDHUP,
            [this, client_fd](int fd) { handle_client(fd); }
        );
    }

    void handle_client(int fd) {
        char buffer[1024];
        ssize_t n = read(fd, buffer, sizeof(buffer));

        if (n <= 0) { // 关闭连接
            if (n < 0) {
                std::cerr << "Read error: " << strerror(errno) << std::endl;
            }
            reactor_.remove_handler(fd);
            close(fd);
            std::cout << "Connection closed" << std::endl;
            return;
        }
        std::cout << "Received: " << buffer << std::endl;
        write(fd, buffer, n); // 回显数据
    }

    Reactor& reactor_;
    int listen_fd_;
};

int main() {
    try {
        Reactor reactor;
        EchoServer server(reactor, 8888);
        
        std::cout << "Echo server running on port 8080..." << std::endl;
        reactor.run_loop();
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}